package main

import (
	"net/http"
	"global/libs/http/app"
	"strings"
	"global/model"
	"global/core"
	"global/libs/structs"
	"github.com/shopspring/decimal"
	"fmt"
	"global/constants"
	"github.com/garyburd/redigo/redis"
)

type responseAnalysisTickerData struct {
	Exchange 		string 		`json:"exchange"`
	Time 			int64 		`json:"time"`
	Symbol 			string 		`json:"symbol"`
	Open 			string 		`json:"open"`
	High	 		string 		`json:"high"`
	Low 			string 		`json:"low"`
	Price 			string 		`json:"price"`
	QuoteChange		string 		`json:"quote_change"`		// 涨跌幅
	PriceSpread 	string 		`json:"price_spread"`		// 价格差价
	SpreadRatio 	string 		`json:"spread_ratio"`		// 差价比
	Volume 			string 		`json:"volume"`
}

func (h *Handler) OnHandleGetAnalysisTicker(writer http.ResponseWriter, request *http.Request)  {

	exchange := strings.ToLower(request.FormValue("exchange"))
	symbol := strings.ToLower(request.FormValue("symbol"))
	if exchange == "" || symbol == "" {
		h.Error(app.ErrParameter)
		return
	}

	// 判断 交易所 和 交易对 是否存在
	has, info, err := model.ExchangeModel.GetItemBySlug(exchange)
	if err != nil || !has {
		h.Error(app.ErrExchangeNotExists)
		return
	}

	if info.Enable != model.ExchangeEnabled {
		h.Error(app.ErrExchangeNotEnable)
		return
	}

	// 检查交易对
	conn := h.ctx.GetBaseRedis().Get()
	defer conn.Close()

	a, err := h.getAnalysisData(conn, exchange, symbol)
	if err != nil {
		h.Error(app.ErrAnalysisDataGetFailed)
		return
	}

	s, err := core.GetSymbolFromExchange(conn, exchange, symbol)
	if err != nil || s == nil {
		h.Error(app.ErrSymbolNotExists)
		return
	}

	// 获取交易对 ticker
	t, err := core.GetTickerForSymbolInExchange(conn, exchange, symbol)
	if err != nil {
		h.Error(app.ErrTickerFailed)
		return
	}

	// 获取 depth
	d, err := core.GetSpiderDepth(conn, exchange, symbol)
	if err != nil {
		h.Error(app.ErrDepthFailed)
		return
	}

	spread, ratio := h.calcPriceSpread(d)
	h.Json(&responseAnalysisTickerData{
		Exchange: 		info.NameEn,
		Symbol: 		symbol,
		Time: 			a.Time,
		Open: 			a.Open,
		High: 			a.High,
		Low: 			a.Low,
		Price: 			t.Close,
		QuoteChange: 	h.calcQuoteChange(t),
		PriceSpread: 	spread,
		SpreadRatio: 	ratio,
		Volume: 		t.Volume,
	})
}

// 计算盘口差价
func (h *Handler) calcPriceSpread(d *structs.Depth) (string, string) {
	var asks, bids, ratio decimal.Decimal
	// 卖单
	if len(d.Asks) > 0 {
		asks, _ = decimal.NewFromString(d.Asks[len(d.Asks) - 1][0])
	}

	// 买单
	if len(d.Bids) > 0 {
		bids, _ = decimal.NewFromString(d.Bids[0][0])
	}

	diff := asks.Sub(bids)
	if !bids.Equal(decimal.Zero) {
		ratio = diff.Div(bids)
	}

	return diff.String(), ratio.StringFixedBank(4)
}

// 计算涨跌幅
func (h *Handler) calcQuoteChange(t *structs.Ticker) string {
	p, _ := decimal.NewFromString(t.Close)
	o, _ := decimal.NewFromString(t.Open)

	if p.Equal(decimal.Zero) {
		return "0.0000"
	}

	tmp := p.Sub(o)
	return tmp.Div(p).StringFixedBank(4)
}

type analysisKlineData struct {
	Time 			int64		`redis:"time"`
	Open 			string		`redis:"open"`
	High 			string		`redis:"high"`
	Low 			string		`redis:"low"`
}


func (h *Handler) getAnalysisData(conn redis.Conn,
	exchange, symbol string) (*analysisKlineData, error) {
	key := fmt.Sprintf(constants.AnalysisKlineData, exchange, symbol)
	vals, err := redis.Values(conn.Do("HGETALL", key))
	if err != nil {
		return nil, err
	}

	var data analysisKlineData
	if err := redis.ScanStruct(vals, &data); err != nil {
		return nil, err
	}

	return &data, nil
}